package com.netty.LongConnect;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;


/**
 * @author: sun.hongliang
 * @create: 2019/02/22 19:41
 */
public class Server {
    private ServerSocketChannel serverSocketChannel;

    public Server(int serverPort) {
        bind(serverPort);
    }

    private void bind(final int port) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                //处理连接
                EventLoopGroup boss = new NioEventLoopGroup();
                EventLoopGroup worker = new NioEventLoopGroup();
                ServerBootstrap bootstrap = new ServerBootstrap();
                bootstrap.group(boss, worker).channel(NioServerSocketChannel.class)
                        .option(ChannelOption.SO_BACKLOG, 128)
                        .option(ChannelOption.TCP_NODELAY, true)
                        .option(ChannelOption.SO_KEEPALIVE, true)
                        .childHandler(new ChannelInitializer<SocketChannel>() {
                            @Override
                            protected void initChannel(SocketChannel ch) throws Exception {
                                ChannelPipeline pipeline = ch.pipeline();
                                pipeline.addLast(
                                        new LineBasedFrameDecoder(1024),
                                        new StringDecoder(),
                                        new MessageDecoder(),
                                        new MessageEncoder(),
                                        new ServerHandler());
                            }
                        });
                ChannelFuture channelFuture;
                try {
                    channelFuture = bootstrap.bind(port).sync();
                    if (channelFuture.isSuccess()) {
                        serverSocketChannel = (ServerSocketChannel) channelFuture.channel();
                        System.out.println("服务端开启成功");
                    }
                    //等待服务监听端口关闭,就是由于这里会将线程阻塞，导致无法发送信息，所以我这里开了线程
                    channelFuture.channel().closeFuture().sync();
                } catch (Exception e) {
                    System.out.println("服务端开启失败");
                    e.printStackTrace();
                } finally {
                    //优雅地退出，释放线程池资源
                    boss.shutdownGracefully();
                    worker.shutdownGracefully();
                }
            }
        });
        thread.start();
    }

    public void sendMessage(Object msg) {
        if (serverSocketChannel != null) {
            serverSocketChannel.writeAndFlush(msg);
        }
    }
}
